package com.group9.handinhand.dao.model;

import java.util.Arrays;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.apache.commons.lang.ArrayUtils;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.beans.BeanUtils;
import org.springframework.social.connect.ConnectionData;

import com.group9.handinhand.service.so.SocialUserSO;

@Entity
@Table(name = "SOCIAL_USER", uniqueConstraints = {@UniqueConstraint(columnNames = { "USER_ID", "PROVIDER_ID", "PROVIDER_USER_ID" }),
        @UniqueConstraint(columnNames = { "USER_ID", "PROVIDER_ID", "RANK" })})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class SocialUser extends AbstractBaseModel {

	private static final long serialVersionUID = 1L;
	
	@ManyToOne(fetch = FetchType.EAGER, optional = false)
	@JoinColumn(name = "USER_ID", nullable = false, updatable = false)
	private User user;
	
	@Column(name = "PROVIDER_ID", nullable = false)
	private String providerId;
	
	@Column(name = "PROVIDER_USER_ID")
	private String providerUserId;
	
	@Column(name = "RANK", nullable = false)
	private int rank;
	
	@Column(name = "DISPLAY_NAME")
	private String displayName;
	
	@Column(name = "PROFILE_URL")
	private String profileUrl;
	
	@Column(name = "IMAGE_URL")
	private String imageUrl;
	
	@Column(name = "ACCESS_TOKEN", nullable = false)
	private String accessToken;
	
	@Column(name = "SECRET")
	private String secret;
	
	@Column(name = "REFRESH_TOKEN")
	private String refreshToken;
	
	@Column(name = "EXPIRE_TIME")
	private long expireTime;
	
	public SocialUserSO convertToServiceObject(String... ignoreProperties) {
		SocialUserSO so = (SocialUserSO) convert(new SocialUserSO(), 
			(String[]) ArrayUtils.addAll(ignoreProperties, new String[]{"user"}));
		if( ! Arrays.asList(ignoreProperties).contains("user"))
			if(user != null)
				so.setUser(user.convertToServiceObject(new String[]{"socialUsers"}));
		return so;
	}
	
	public SocialUser buildFromConnectionData(ConnectionData connectionData) {
		BeanUtils.copyProperties(connectionData, this);	
		return this;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getProviderId() {
		return providerId;
	}

	public void setProviderId(String providerId) {
		this.providerId = providerId;
	}

	public String getProviderUserId() {
		return providerUserId;
	}

	public void setProviderUserId(String providerUserId) {
		this.providerUserId = providerUserId;
	}

	public int getRank() {
		return rank;
	}

	public void setRank(int rank) {
		this.rank = rank;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getProfileUrl() {
		return profileUrl;
	}

	public void setProfileUrl(String profileUrl) {
		this.profileUrl = profileUrl;
	}

	public String getImageUrl() {
		return imageUrl;
	}

	public void setImageUrl(String imageUrl) {
		this.imageUrl = imageUrl;
	}

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public String getSecret() {
		return secret;
	}

	public void setSecret(String secret) {
		this.secret = secret;
	}

	public String getRefreshToken() {
		return refreshToken;
	}

	public void setRefreshToken(String refreshToken) {
		this.refreshToken = refreshToken;
	}

	public long getExpireTime() {
		return expireTime;
	}

	public void setExpireTime(long expireTime) {
		this.expireTime = expireTime;
	}

	@Override
	public String toString() {
		return "SocialUser [user=" + user + ", providerId=" + providerId
				+ ", providerUserId=" + providerUserId + ", rank=" + rank
				+ ", displayName=" + displayName + ", profileUrl=" + profileUrl
				+ ", imageUrl=" + imageUrl + ", accessToken=" + accessToken
				+ ", secret=" + secret + ", refreshToken=" + refreshToken
				+ ", expireTime=" + expireTime + "]";
	}

}
